﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Security.Cryptography;

namespace BuXiaChu.OrderDishes.BLL.StaticCache
{
    public class StaticCacheImage
    {
        public static StaticCacheImage Instance { get; private set; }
        public string CachePath { get; set; }
        public int CacheSubDirs { get; set; }

        static StaticCacheImage()
        {
            Instance = new StaticCacheImage();
        }

        private StaticCacheImage()
        {
            //CachePath = HttpContext.Current.Server.MapPath(ConfigurationManager.AppSettings["Cache.Menu.Images"]);
            CacheSubDirs = 100;
        }

        private string GetCorrectKey(string key)
        {
            return key.Trim().ToLower();
        }

        private string GetCacheFileName(string key)
        {
            #region
            //var extensionName = Path.GetExtension(key);
            //key = GetCorrectKey(Path.GetFileNameWithoutExtension(key));
            key = GetCorrectKey(key);

            var subPath = Math.Abs(key.GetHashCode()) % CacheSubDirs;
            var path = Path.Combine(CachePath, subPath.ToString());
            if (Directory.Exists(path) == false) Directory.CreateDirectory(path);
            var md5 = new MD5CryptoServiceProvider().ComputeHash(ASCIIEncoding.ASCII.GetBytes(key));
            var sb = new StringBuilder();
            foreach (byte b in md5)
            {
                sb.Append(Convert.ToString(b));
            }

            //var fileName = ASCIIEncoding.ASCII.GetString(md5);

            return Path.Combine(path, sb.ToString());//extensionName
            #endregion
        }

        public void Set(string key, object value)
        {
            #region
            var fileName = GetCacheFileName(key);
            using (var fileStream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write))
            {
                var b = (byte[])value;
                fileStream.Write(b, 0, b.Length);
            }
            #endregion
        }

        /// <summary>
        /// menu
        /// </summary>
        /// <returns></returns>
        public byte[] Get(string key)
        {
            #region
            var fileName = GetCacheFileName(key);
            if (File.Exists(fileName))
            {
                using (var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
                {
                    int len = int.Parse(stream.Length.ToString());
                    byte[] array = new byte[len];

                    stream.Read(array, 0, len);

                    return array;
                }
            }
            return null;
            #endregion
        }

        public bool TryGet(string key, out byte[] value)
        {
            #region
            value = Get(key);
            if (value == null)
            {
                return false;
            }
            return true;
            #endregion
        }

        public void Delete(string key)
        {
            File.Delete(GetCacheFileName(key));
        }
    }
}
